package org.zxp.thread.communication;

/**
 * @program: zxp-thread-test
 * @description: 演示wait notify
 * @author: X-Pacific zhang
 * @create: 2019-05-19 11:20
 **/
public class WaitTest {
    public static void main(String[] args){
        Object o = new Object();
        new Thread(() -> {
            System.out.println("t1 begin");
            //获得o对象的锁
            synchronized (o){
                try {
                    System.out.println("t1 get lock o");
                    //阻塞当前线程，并释放o的锁
                    o.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            System.out.println("t1 over");
        }).start();
        try {
            //1秒后唤醒第一个线程
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        new Thread(() -> {
            System.out.println("t2 begin");
            //获得o对象的锁，因为上面o.wait();已经释放了锁
            synchronized (o){
                System.out.println("t2 get lock o");
                //唤醒第一个线程
                o.notifyAll();
            }
            System.out.println("t2 over");
        }).start();


//        Object o = new Object();
//        new Thread(() -> {
//            synchronized (o){
//                try {
//                    System.out.println("t1 wait");
//                    o.wait();
//                    System.out.println("t1 resume");
//                    synchronized (o){
//                        System.out.println("t1 hold lock o");
//                    }
//                } catch (InterruptedException e) {
//                    e.printStackTrace();
//                }
//            }
//        }).start();
//        try {
//            Thread.sleep(1000);
//        } catch (InterruptedException e) {
//            e.printStackTrace();
//        }
//        new Thread(() -> {
//            synchronized (o){
//                System.out.println("t2");
//                o.notifyAll();
//                System.out.println("t22");
        //唤醒后，锁仍由第二个线程持有，notify只是做到了线程1的o.wait();可能唤醒，还差一个条件线程1才能真正被唤醒，即线程2释放锁
        //由于synchronized是可重入锁，所以这块可以进去
////                synchronized (o){
////                    System.out.println("t2 hold lock o");
////                }
        //如果这块是个死循环，即这个线程永远持有了o的锁，线程1由于等待线程2释放锁，所以线程1死锁
////                while(true){}
//                try {
        //3秒后线程2释放锁，线程1o.wait();真正被唤醒，并持有锁，继续运行
//                    Thread.sleep(3000);
//                } catch (InterruptedException e) {
//                    e.printStackTrace();
//                }
//            }
//        }).start();
    }
}
